package com.palm.easy.controller;


import com.palm.easy.Current;
import com.palm.easy.ManagerConfiguration;
import com.palm.easy.SystemMenus;
import com.palm.easy.anno.Auth;
import com.palm.easy.anno.Menu;
import com.palm.easy.anno.impl.AuthHandler;
import com.palm.easy.domain.MenuItem;
import com.palm.easy.domain.User;
import com.palm.easy.domain.UserInfo;
import com.palm.easy.service.ConfigService;
import com.palm.easy.service.NginxService;
import com.palm.easy.util.Captcha;
import com.palm.easy.util.StringUtil;
import org.noear.snack.ONode;
import org.noear.snack.core.TypeRef;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.core.handle.Result;

import java.io.File;
import java.lang.reflect.Field;
import java.sql.Array;
import java.util.*;

@Auth
@Controller
@Mapping("system")
public class SystemController {
    @Inject
    NginxService nginxService;
    @Inject
    ConfigService configService;

    private File usersFile;
    Map<String,User> userMap;

    List<MenuItem> menus = new ArrayList<>();
    @Init
    public void init() {
        String basePath = ManagerConfiguration.localPath();
        usersFile=new File(basePath,"conf/users.json");
        if(usersFile.exists()){
            userMap=ONode.deserialize(StringUtil.readFrom(usersFile),new TypeRef<Map<String,User>>(){}.getType());
        }else{
            userMap=new HashMap<>();
        }
        if(!userMap.containsKey("admin")){//初始化admin用户
            User admin=new User();
            admin.setUsername("admin");
            admin.setPassword("admin");
            admin.setName("管理员");
            userMap.put("admin",admin);
            StringUtil.write(usersFile,ONode.serialize(userMap));
        }
        //init users;
        //init menu
        for (Field field : SystemMenus.class.getDeclaredFields()) {
            if (field.getType() != String.class) {
                continue;
            }
            Menu m = field.getAnnotation(Menu.class);
            if (m == null) {
                continue;
            }
            MenuItem it = new MenuItem();
            it.setIcon(m.icon());
            it.setTitle(m.value());
            it.setPath(m.path());
            it.setOrder(m.order());
            try {
                it.setKey((String) field.get(SystemMenus.class));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            menus.add(it);
        }
        Collections.sort(menus);


        AuthHandler.setUserLoader(this::loadUser);
    }
    private UserInfo loadUser(String name){
        User user=userMap.get(name);
        if(user!=null){
            UserInfo userInfo=new UserInfo();
            userInfo.setUsername(user.getUsername());
            userInfo.setName(user.getName());
            userInfo.setPassword(user.getPassword());
            userInfo.setMenu(menus);
            return userInfo;
        }
        return null;
    }

    /**==========  user infos   ================**/
    @Mapping(value = "user_info", method = MethodType.GET)
    public Result<UserInfo> userInfo(Context ctx) {
        UserInfo userInfo=Current.user();
        //Current.setLoginToken(ctx,userInfo);
        return Result.succeed(userInfo);
    }
    @Auth(login = false)
    @Mapping("login")
    public Result login(String username, String password, String verify) {
        Context ctx = Context.current();
        if (!Captcha.verify(verify, ctx)) {
            return Result.failure("验证码错误");
        }
        if (StringUtil.isEmpty(password)) {
            return Result.failure("用户名或密码错误");
        }
       //
        User user=userMap.get(username);
        if(user==null || !password.equals(user.getPassword())){
            return Result.failure("用户名或密码错误");
        }
        UserInfo userInfo = loadUser(username);
        Current.setUser(userInfo);
        return Result.succeed();
    }
    @Post
    @Mapping("changePassword")
    public Result changePassword(String ConfirmPassword, String OldPassword,String Password){
        if(!Objects.equals(ConfirmPassword,Password)){
            return Result.failure("两次输入密码不一致!");
        }
        UserInfo current=Current.user();
        if(!Objects.equals(OldPassword,current.getPassword())){
            return Result.failure("原密码不正确!");
        }
        User user=userMap.get(current.getUsername());
        user.setPassword(Password);
        current.setPassword(Password);
        StringUtil.write(usersFile,ONode.serialize(userMap));
        return Result.succeed(null,"密码已修改");
    }
    @Mapping("logout")
    public Result logout(Context ctx){
        //ctx.sessionClear();
        //ctx.cookieSet("_t",null);
        Current.logout(ctx);
        return Result.succeed();
    }
    @Auth(login = false)
    @Note("保持在线")
    @Mapping("keep")
    public Result keepOnline() {
       // Context ctx = Context.current();
        Current.user();
        return Result.succeed();
//        if(user!=null){
//           // Current.setLoginToken(ctx,user);
//            return Result.succeed(user.getUsername());
//        }
//        return Result.failure();
    }



    @Mapping("save_configs")
    public Result saveConfig(Map<String,String> configs){
//        String config= ONode.stringify(ctx.paramMap());//JSON.toJSONString(ctx.paramMap());
//        configService.saveConfig("configs",config);
        configService.saveAll(configs);
        return Result.succeed();
    }
    @Mapping("get_configs")
    public Result getConfig(){
        return Result.succeed(configService.getConfigs());
    }
    @Mapping("save_config")
    public Result saveConfig(Context ctx){
        String config= ONode.stringify(ctx.paramMap());//JSON.toJSONString(ctx.paramMap());
        configService.saveConfig("configs",config);
        return Result.succeed();
    }

    @Mapping("nginxStatus")
    public Result getNginxStatus(){
        return Result.succeed(nginxService.status()?"运行":"停止");
    }
    @Mapping(method = MethodType.GET,value = "nginxCfg")
    public Result getNginxCfg(){
        Map data=new HashMap();
        data.put("path",nginxService.getPath());
        data.put("config",nginxService.getConfigTemplate());
        return Result.succeed(data);
    }
    @Mapping(method = MethodType.POST,value = "nginxCfg")
    public Result saveNginxCfg(String path,String config){
        try {
            nginxService.saveNginxCfg(path, config);
            return Result.succeed();
        }catch (Exception e){
            e.printStackTrace();
            return Result.failure(e.getMessage());
        }

    }
    @Mapping("nginxCmd")
    public Result nginxCmd(String cmd){
        if(StringUtil.isEmpty(cmd)){
            return Result.failure("命令错误");
        }
        switch (cmd){
            case "start":
                return nginxService.start(false);
            case "stop":
                return nginxService.stop();
            case "reload":
                return nginxService.reload();
        }
        return Result.failure("命令错误");
    }
    @Mapping("nginxPreviewCfg")
    public Result nginxPreviewCfg(){
        return nginxService.previewCfg();
    }

}
